import FileWorker from './file.worker.js'
// 文件分片
// 定义块大小
const CHUNK_SIZE = 1024 * 1024 * 5; // 5MB
// 定义线程数 navigator.hardwareConcurrency 获取当前设备的核心数，若是单核心的，则取1个核心 默认取1/2
/**
 * 定义线程数
 * navigator.hardwareConcurrency 获取当前设备的核心数
 * 若是单核心的，则取1个核心
 * 否多核心，则取核心数的1/2个核心
 * 若navigator.hardwareConcurrency 不支持，则默认2个
 * @type {number|number}
 */
const THREAD_COUNT = navigator.hardwareConcurrency === 1 ? 1 : Math.ceil(navigator.hardwareConcurrency / 2) || 2;

/**
 * 文件分片通用方法
 * @param file
 * @returns {Promise<unknown>}
 */
export async function cutFile(file){
  return new Promise(resolve=>{
    // 计算分片总数
    const chunkCount = Math.ceil(file.size / CHUNK_SIZE);
    // 计算每个线程分配的任务数量
    const threadChunkCount = Math.ceil(chunkCount / THREAD_COUNT);
    const result = [];
    // 统计线程完成任务数量
    let finishCount = 0;
    for (let i = 0; i < THREAD_COUNT; i++) {
      // 分配线程任务
      const worker = new FileWorker()
      // 计算线程任务范围
      const start = i * threadChunkCount;
      let end = (i + 1) * threadChunkCount;
      // 线程任务范围超出分片总数，则取分片总数
      if (end > chunkCount) {
        end = chunkCount;
      }
      worker.postMessage({
        file,
        start,
        end,
        CHUNK_SIZE
      });
      worker.onmessage = e=> {
        // 按顺序依次放入数组，防止多线程并发时造成结果乱序
        for (let i = start; i < end; i++) {
          result[i] = e.data[i - start]
        }
        worker.terminate();
        finishCount++;
        if (finishCount === THREAD_COUNT) {
          resolve(result.flat());
        }
      };
    }
  })
}



